package com.lty.jeeg.server.modules.fas.service.impl;

import com.lty.jeeg.server.common.enums.ResponseEnum;
import com.lty.jeeg.server.common.page.table.PageTableHandler;
import com.lty.jeeg.server.common.page.table.PageTableRequest;
import com.lty.jeeg.server.common.page.table.PageTableResponse;
import com.lty.jeeg.server.common.utils.BeanConverter;
import com.lty.jeeg.server.common.utils.UserUtil;
import com.lty.jeeg.server.modules.fas.dao.GoodsDao;
import com.lty.jeeg.server.modules.fas.dao.StockDao;
import com.lty.jeeg.server.modules.fas.dto.GoodsCategoryDTO;
import com.lty.jeeg.server.modules.fas.dto.GoodsDTO;
import com.lty.jeeg.server.modules.fas.dto.HandOverDTO;
import com.lty.jeeg.server.modules.fas.dto.StockDTO;
import com.lty.jeeg.server.modules.fas.export.HandOverExportEntity;
import com.lty.jeeg.server.modules.fas.model.Goods;
import com.lty.jeeg.server.modules.fas.model.Stock;
import com.lty.jeeg.server.modules.fas.service.GoodsCategoryService;
import com.lty.jeeg.server.modules.fas.service.StockService;
import com.lty.jeeg.server.modules.sys.dao.DeptDao;
import com.lty.jeeg.server.modules.sys.dao.UserDao;
import com.lty.jeeg.server.modules.sys.model.Dept;
import com.lty.jeeg.server.modules.sys.model.User;
import com.lty.jeeg.server.modules.sys.service.DeptService;
import com.lty.jeeg.server.modules.sys.service.impl.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lty.jeeg.server.modules.fas.dao.HandOverDao;
import com.lty.jeeg.server.modules.fas.model.HandOver;
import com.lty.jeeg.server.modules.fas.service.HandOverService;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

import static com.lty.jeeg.server.common.constant.BizConstant.FAS_ADMIN_STORE_DEPT_ID;
import static com.lty.jeeg.server.common.constant.BizConstant.FAS_WASTE_STORE_DEPT_ID;

/**
 * @author : zl
 * @date : 2019-02-13 14:56:11
 * Description : 调拨记录
 */
@Service
@Slf4j
public class HandOverServiceImpl implements HandOverService {

    private final HandOverDao handOverDao;
    @Autowired
    private StockDao stockDao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private DeptDao deptDao;
    @Autowired
    private StockService stockService;


    @Autowired
    private GoodsCategoryService goodsCategoryService;

    @Autowired
    private DeptService deptService;

    @Autowired
    public HandOverServiceImpl(HandOverDao handOverDao) {
        this.handOverDao = handOverDao;
    }

    @Override
    public HandOver getById(Long id) {
        return handOverDao.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(Long id) {
        log.debug("删除HandOver=>{}", id);
        return handOverDao.delete(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(HandOver handOver) {
        handOver.preUpdate();
        log.debug("修改HandOver=>{}", handOver.getId());
        return handOverDao.update(handOver);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEnum save(HandOver handOver) {
        if (handOver.getUpdateTime() == null) {
            handOver.setUpdateTime(new Date());
        }
        if (handOver.getCreateTime() == null) {
            handOver.setCreateTime(new Date());
        }
        //添加创建人及修改人
        handOver.preInsert();
        //修改对应的部门或个人的库存
        //来源用户id
        Long userId = handOver.getHandlerId();
        //来源部门id
        Long deptId = handOver.getDeployComeId();
        //目标用户id
        Long userId2 = handOver.getDeployForpeoId();
        //目标部门id
        Long deptId2 = handOver.getDeployForId();
        //商品id
        Long goodsId = handOver.getGoodsId();
        //来源商品id
        Long fid = null;
        //目标商品id
        Long tid = null;
        if (goodsId != null) {
            if (userId != null && deptId != null) {
                //来源用户库商品
                fid = stockDao.getIdByUserLib(goodsId, userId, deptId);
            } else if (userId == null && deptId != null) {
                //来源部门库商品
                fid = stockDao.getIdByDeptLib(goodsId, deptId);
            }
            if (userId2 != null && deptId2 != null) {
                //目标用户库商品
                tid = stockDao.getIdByUserLib(goodsId, userId2, deptId2);
            } else if (userId2 == null && deptId2 != null) {
                //目标部门库商品
                tid = stockDao.getIdByDeptLib(goodsId, deptId2);
            }
        } else {
            //error请选择商品
            return ResponseEnum.GOODS_NOT_EXIST;
        }
        //判断来源部门是否有该商品库存
        if (fid != null) {
            //查询来源部门库存信息
            StockDTO dtof = stockDao.getById(fid);
            //查询需求部门库存信息
            //StockDTO dtot=stockDao.getById(tid);
            //查询来货部门库存总数量
            int totalf = dtof.getTotalNumber();
            //查询需求部门库存总数量
            //int totalt=dtot.getTotalNumber();
            //获取需求数量
            Integer need = handOver.getDetailNum().intValue();
            if (need > totalf) {
                //调拨数量大于调拨库存量
                return ResponseEnum.GOODS_STOCK_ERROR;
            } else {
                //非常规的商品需要填写来源用户和目标用户
                Goods goods = goodsDao.getById(handOver.getGoodsId());
                if ("0".equals(goods.getIsCommon().toString()) && (userId == null || userId2 == null)) {
                    return ResponseEnum.FORM_INFO_INCOMPLETE;
                } else {
                    //修改对应两个库存的库存量
                    //来源库存减去调拨数量
                    StockDTO fDto = stockDao.getById(fid);
                    fDto.setTotalNumber(fDto.getTotalNumber() - need);
                    Stock fs = BeanConverter.map(fDto, Stock.class);
                    stockDao.update(fs);
                    //获取商品信息
                    GoodsDTO goodsDTO = goodsDao.getById(goodsId);
                    //需求部门有此库存，修改需求部门库存数量
                    if (tid != null) {
                        StockDTO tDto = stockDao.getById(tid);
                        //目标库存加上调拨数量
                        tDto.setTotalNumber(tDto.getTotalNumber() + need);
                        Stock ts = BeanConverter.map(tDto, Stock.class);
                        stockDao.update(ts);
                        // 需求部门无此库存，新添需求部门库存
                    } else {
                        Stock newStock = new StockDTO();
                        //获取商品分类Id
                        Long caId = goodsDTO.getCategory();
                        //查询商品分类信息
                        GoodsCategoryDTO goodsCategoryDTO = goodsCategoryService.getById(caId.longValue());
                        //保存商品分类父类Id
                        Long parentCategory = goodsCategoryDTO.getParentId();
                        newStock.setParentCategory(parentCategory);
                        newStock.setGoodsId(goodsId);
                        newStock.setCategory(goods.getCategory());
                        //判断是人员库存还是部门库存
                        if (userId2 != null) {
                            newStock.setUserId(userId2);
                        }
                        newStock.setDeptId(deptId2);
                        Dept dept = deptDao.getById(deptId2);
                        newStock.setCompanyId(dept.getCompany());

                        newStock.setTotalNumber(need);
                        newStock.setIdleNumber(0);
                        stockDao.save(newStock);
                    }
                    //属性值复制
                    HandOver ho = BeanConverter.map(handOver, HandOver.class);
                    //获取行政部信息
                    Dept dept = deptService.getById(FAS_ADMIN_STORE_DEPT_ID);
                    //目标部门是为行政部保存一条记录
                    if (deptId2.equals(FAS_ADMIN_STORE_DEPT_ID)) {
                        ho.setHandleType(30);
                        ho.setDeployForId(dept.getId());
                        ho.setDeployForName(dept.getName());
                        handOverDao.save(ho);
                        //来源部门为行政部保留一条记录
                    } else if (deptId.equals(FAS_ADMIN_STORE_DEPT_ID)) {
                        //添加行政部到调拨库的调拨记录
                        ho = BeanConverter.map(handOver, HandOver.class);
                        ho.setHandleType(30);
                        ho.setDeployComeId(dept.getId());
                        ho.setDeployComeName(dept.getName());
                        handOverDao.save(ho);
                        //需求部门与来源部门一致时返回异常
                    } else if (deptId2.equals(deptId)) {
                        return ResponseEnum.HAND_OVER_DEPTS_SHOULD_NOT_SAME;
                    } else {//需求部门与来货部门都不为行政部时保留两条记录
                        //添加来源库到行政部的调拨记录
                        ho.setHandleType(30);
                        ho.setDeployForId(dept.getId());
                        ho.setDeployForName(dept.getName());
                        ho.setDeployForpeoId(null);
                        ho.setDeployForpeoName("");
                        handOverDao.save(ho);
                        //添加行政部到调拨库的调拨记录
                        ho = BeanConverter.map(handOver, HandOver.class);
                        ho.setHandleType(30);
                        ho.setDeployComeId(dept.getId());
                        ho.setDeployComeName(dept.getName());
                        ho.setHandlerId(null);
                        ho.setHandlerName("");
                        handOverDao.save(ho);
                    }
                }
            }
        } else {
            //没有找到对应的库存商品
            return ResponseEnum.GOODS_NOT_EXIST;
        }
        //保存调拨记录

        log.debug("新增HandOver=>{}", handOver.getId());
        return ResponseEnum.SUCCESS;
    }

    @Override
    public ResponseEnum discard(HandOver handOver) {
        handOver.preInsert();
        //判断是报废还是置换 置换先判断行政仓有没有此商品
        Long goodsId = handOver.getGoodsId();
        //行政仓部门Id
        Long deptId = FAS_ADMIN_STORE_DEPT_ID;
        //获取操作类型
        Integer type = handOver.getHandleType();
        //置换
        if (type != null) {
            //根据商品ID与部门ID查询行政仓是否有次库存
            Stock stock = stockDao.getByGoodsIdAndDeptId(goodsId, deptId);
            //根据商品ID与置换部门ID查询置换部门是否有此库存
            Stock disStock = stockDao.getByGoodsIdAndDeptId(goodsId, handOver.getDeployComeId());
            int total = 0;
            //行政仓无此库存，返回库存不足
            if("50".equals(type)){//置换查看行政仓与需求部门商品都有库存
                if(stock == null){
                    return ResponseEnum.GOODS_STOCK_ERROR;
                }else if (disStock == null){
                    return ResponseEnum.GOODS_STOCK_ERROR;
                }
                //获取行政仓总数量
                total = stock.getTotalNumber();
            }else{//报废查看需求部门商品有此库存
                if(disStock == null){
                    return ResponseEnum.GOODS_STATUS_DEPT_NULL;
                }
                //获取要报废部门库存总数量
                total = disStock.getTotalNumber();
            }

            //获取报废或者置换数量
            int need = handOver.getDetailNum().intValue();
            //报废或者置换数量大于总数量时
            if (need > total) {
                return ResponseEnum.GOODS_STOCK_ERROR;
            }
            //修改
            if (handOver.getId() != null) {
                //修改操作不能再提交审批之后进行
                if (handOver.getDiscardType() == 0) {
                    handOverDao.updateDis(handOver);
                } else {
                    return ResponseEnum.APPROVAL_STATUS_CANNOT_MODIFY;
                }
            } else {//新增
                handOverDao.save(handOver);
            }
        }
        return ResponseEnum.SUCCESS;
    }

    @Override
    public PageTableResponse list(PageTableRequest request) {
        request.getParams().put("dsf", BaseService.dataScopeFilter("fas", UserUtil.getCurrentUser(), "du1", "ua"));
        return new PageTableHandler(
                request1 -> handOverDao.count(request1.getParams()),
                request2 -> handOverDao.list(
                        request2.getParams(), request2.getOffset(), request2.getLimit()))
                .handle(request);
    }

    /**
     * 出入库记录数据(用于导出)
     *
     * @param handOverDTO
     * @return
     */
    @Override
    public List<HandOverExportEntity> getExportDatas(HandOverDTO handOverDTO) {
        return handOverDao.getExportDatas(handOverDTO);
    }

    @Override
    public ResponseEnum approval(HttpServletRequest request) {
        //获取置换或者报废单Id
        String id = request.getParameter("id");
        //获取置换或者报废的type
        String type = request.getParameter("type");
        Long hId;
        //报废或者置换单id及报废或者置换的类型不为空
        if (StringUtils.isNotEmpty(id) && StringUtils.isNotEmpty(type)) {
            //置换或者报废单Id转为long型
            hId = Long.valueOf(id);
            //审批状态
            Integer status = 0;

            if ("submit".equals(type)) {//提交
                status = 1;
            } else if ("withdraw".equals(type) || "reject".equals(type)) {//撤回或者驳回
                status = 0;
            } else if ("confirm".equals(type)) {//审批通过
                status = 4;
                //根据置换或报废单ID获取置换或者报废信息
                HandOver handOver = handOverDao.getById(hId);
                //获取置换还是报废类型
                Integer hType = handOver.getHandleType();
                //置换或者报废的数量
                int num = handOver.getDetailNum().intValue();
                //40-报废 50-置换
                if (hType != null) {
                    //行政仓-71L 报废仓-72L
                    Dept xingzh = deptService.getById(FAS_ADMIN_STORE_DEPT_ID);
                    Dept baofei = deptService.getById(FAS_WASTE_STORE_DEPT_ID);
                    //获取报废或者置换部门ID
                    Long comeId = handOver.getDeployComeId();
                    //获取报废或者置换部门信息
                    Dept comeDept = deptService.getById(comeId);
                    //报废或置换的人员
                    Long userId = handOver.getHandlerId();
                    //报废或者置换的商品
                    Long goodsId = handOver.getGoodsId();
                    //商品信息
                    if (goodsId != null) {
                        Goods goods = goodsDao.getById(goodsId);
                        handOver.setDetailUnit(goods.getUnit());
                        handOver.setDetailSpec(goods.getSpecification());
                    }
                    if (40 == hType) {
                        //部门到报废仓
                        ResponseEnum chEm = checkStack(handOver);
                        if (chEm.getCode() == 0) {
                            //添加出入库记录 报废--报废部门到报废仓
                            HandOver inOver = BeanConverter.map(handOver, HandOver.class);
                            inOver.setDeployComeId(comeDept.getId());
                            inOver.setDeployComeName(comeDept.getName());
                            inOver.setDeployForId(baofei.getId());
                            inOver.setDeployForName(baofei.getName());
                            if (userId != null) {
                                User user = userDao.getById(userId);
                                inOver.setHandlerId(userId);
                                inOver.setHandlerName(user.getNickname());
                            }
                            handOverDao.save(inOver);
                        } else {
                            return chEm;
                        }

                    } else if (50 == hType) {
                        ResponseEnum chEm = checkStack(handOver);
                        if (chEm.getCode() == 0) {
                            //添加出入库记录 置换--报废部门到报废仓--行政仓到报废部门
                            HandOver inOver = BeanConverter.map(handOver, HandOver.class);
                            inOver.setDeployComeId(comeDept.getId());
                            inOver.setDeployComeName(comeDept.getName());
                            inOver.setDeployForId(baofei.getId());
                            inOver.setDeployForName(baofei.getName());
                            if (userId != null) {
                                User user = userDao.getById(userId);
                                inOver.setHandlerId(userId);
                                inOver.setHandlerName(user.getNickname());
                            }
                            handOverDao.save(inOver);
                            HandOver outOver = BeanConverter.map(handOver, HandOver.class);
                            outOver.setHandlerId(null);
                            outOver.setHandlerName("");
                            outOver.setDeployComeId(xingzh.getId());
                            outOver.setDeployComeName(xingzh.getName());
                            outOver.setDeployForId(comeDept.getId());
                            outOver.setDeployForName(comeDept.getName());
                            if (userId != null) {
                                User user = userDao.getById(userId);
                                outOver.setDeployForpeoId(userId);
                                outOver.setDeployForpeoName(user.getNickname());
                            }
                            handOverDao.save(outOver);

                        } else {
                            return chEm;
                        }
                    }
                }

            }
            handOverDao.changeStatus(hId, status);
            return ResponseEnum.SUCCESS;
        } else {
            return ResponseEnum.ORDER_NOT_EXIST;
        }
    }

    /**
     * 判断部门内商品的库存是否可用
     *
     * @param handOver
     * @return
     */
    ResponseEnum checkStack(HandOver handOver) {
        Integer hType = handOver.getHandleType();
        if (hType != null) {
            //行政仓
            Long xzc = FAS_ADMIN_STORE_DEPT_ID;
            //报废仓
            Long bfc = FAS_WASTE_STORE_DEPT_ID;
            //报废部门
            Long comeId = handOver.getDeployComeId();
            //报废人员
            Long userId = handOver.getHandlerId();
            //商品ID
            Long goodsId = handOver.getGoodsId();
            //需求数量
            Integer num = handOver.getDetailNum().intValue();
            //报废
            if (40 == hType) {
                //报废部门报废商品库存
                Stock stock = stockDao.getCheck(goodsId, comeId, userId);
                //报废部门库或人员库没有此商品
                if (stock == null) {
                    return ResponseEnum.GOODS_STATUS_NULL;
                    //报废部门库或人员库此商品与报废数量错误
                } else if (stock.getTotalNumber() < handOver.getDetailNum().intValue()) {
                    return ResponseEnum.GOODS_NOT_EXIST;
                }
                //获取报废仓信息
                Stock discardStock = stockDao.getCheck(goodsId, bfc, null);
                //获取商品信息
                Goods goods = goodsDao.getById(goodsId);
                //商品分类Id
                Long caId = goods.getCategory();
                GoodsCategoryDTO goodsCategory = goodsCategoryService.getById(caId);
                //商品分类父级
                Long parentCategory = goodsCategory.getParentId();
                //新增报废仓商品
                if(discardStock == null){
                    Stock disStock = new Stock();
                    disStock.setGoodsId(goodsId);
                    disStock.setCategory(caId);
                    disStock.setParentCategory(parentCategory);
                    disStock.setDeptId(bfc);
                    disStock.setTotalNumber(num);
                    disStock.setIdleNumber(num);
                    stockDao.save(disStock);
                }else{//修改报废仓
                    discardStock.setTotalNumber(discardStock.getTotalNumber() + num);
                    //修改闲置数量
                    discardStock.setIdleNumber(discardStock.getIdleNumber() + num);
                    stockDao.update(discardStock);
                }
                //修改报废部门库存
                stock.setTotalNumber(stock.getTotalNumber() - num);
                stockDao.update(stock);

            } else {//置换
                //报废部门报废商品库存
                Stock stockbf = stockDao.getCheck(goodsId, comeId, userId);
                //行政仓库存
                Stock stockxz = stockDao.getByGoodsIdAndDeptId(goodsId, FAS_ADMIN_STORE_DEPT_ID);
                //报废部门库或人员库没有此商品库存
                if (stockbf == null) {
                    return ResponseEnum.GOODS_STATUS_NULL;
                    //报废部门库或人员库此商品与报废数量错误
                } else if (stockbf.getTotalNumber() < handOver.getDetailNum().intValue()) {
                    return ResponseEnum.GOODS_NOT_EXIST;
                }
                //行政仓没有此商品库存
                if (stockxz == null) {
                    return ResponseEnum.GOODS_STOCK_ERROR;
                    //行政仓没有足够的置换数量
                } else if (stockxz.getTotalNumber() < handOver.getDetailNum().intValue()) {
                    return ResponseEnum.GOODS_STOCK_ERROR;
                }
                //行政仓减num，报废仓加num
                stockxz.setTotalNumber(stockxz.getTotalNumber() - num);
                stockDao.update(stockxz);
                //获取商品信息
                Goods goods = goodsDao.getById(goodsId);
                //获取报废仓信息
                Stock discardStock = stockDao.getCheck(goodsId, bfc, null);
                Long caId = goods.getCategory();
                GoodsCategoryDTO goodsCategory = goodsCategoryService.getById(caId);
                Long parentCategory = goodsCategory.getParentId();
                //判断报废仓商品库存信息
                if(discardStock == null){//新增报废仓库存
                    Stock disStock = new Stock();
                    disStock.setGoodsId(goodsId);
                    disStock.setCategory(caId);
                    disStock.setParentCategory(parentCategory);
                    disStock.setDeptId(bfc);
                    disStock.setTotalNumber(num);
                    disStock.setIdleNumber(num);
                    stockService.save(disStock);
                }else{//修改报废仓库存
                    discardStock.setTotalNumber(discardStock.getTotalNumber() + num);
                    //修改闲置数量
                    discardStock.setIdleNumber(discardStock.getIdleNumber() + num);
                    stockDao.update(discardStock);
                }

            }
        }
        return ResponseEnum.SUCCESS;
    }
}
